import { AxiosRequestConfig } from '../types'
import { isPlainObject, deepMerge } from '../helpers/util'

const strats = Object.create(null)
/**
 * 描述 默认策略 使用自定义配置
 * @param {any} defaultVal  默认配置值
 * @param {any} customVal   自定义配置值
 * @returns {any}
 */
function defaultStrat(defaultVal: any, customVal: any): any {
  return typeof customVal === 'undefined' ? defaultVal : customVal
}

function deepMergeStrat(defaultVal: any, customVal: any): any {
  if (isPlainObject(customVal)) {
    return deepMerge(customVal)
  } else if (typeof customVal !== 'undefined') {
    return customVal
  } else if (isPlainObject(defaultVal)) {
    return deepMerge(defaultVal)
  } else if (typeof defaultVal !== 'undefined') {
    return defaultVal
  }
}

/**
 * 描述 优先使用自定义配置
 * @param {any} defaultVal
 * @param {any} customVal
 * @returns {any}
 */
function fromCustomStrat(defaultVal: any, customVal: any): any {
  if (typeof customVal !== 'undefined') {
    return customVal
  }
}

const fromCustomConfigKeys = ['method', 'data', 'params']

fromCustomConfigKeys.forEach((key) => {
  strats[key] = fromCustomStrat
})

const deepMergeKeys = ['headers', 'auth']

deepMergeKeys.forEach((key) => {
  strats[key] = deepMergeStrat
})

export default function mergeConfig(
  defaultConfig: AxiosRequestConfig,
  customConfig?: AxiosRequestConfig
): AxiosRequestConfig {
  if (!customConfig) {
    customConfig = {}
  }
  // 空对象
  let config = Object.create(null)

  for (let key in customConfig) {
    mergeField(key)
  }

  for (let key in defaultConfig) {
    if (!customConfig[key]) {
      mergeField(key)
    }
  }

  function mergeField(key: string) {
    const strat = strats[key] || defaultStrat
    config[key] = strat(defaultConfig[key], customConfig![key])
  }

  return config
}
